// 动态符号表系统

use std::collections::HashMap;
use crate::utils::{tokenize, is_chinese_text};

// 符号类型枚举
#[derive(Debug, Clone, PartialEq)]
pub enum SymbolType {
    Word,          // 单词
    Punctuation,   // 标点符号
    Number,        // 数字
    Unknown,       // 未知类型
}

// 符号结构体
#[derive(Debug, Clone)]
pub struct Symbol {
    pub text: String,
    pub symbol_type: SymbolType,
    pub frequency: f32,
    pub last_access: u64,
    pub relations: HashMap<usize, f32>, // 符号ID -> 关系强度
}

// 动态符号表
#[derive(Debug)]
pub struct SymbolTable {
    pub symbols: HashMap<usize, Symbol>,
    pub text_to_id: HashMap<String, usize>,
    pub id_to_symbol: HashMap<usize, String>,
    pub next_id: usize,
    pub current_time: u64,
}

impl SymbolTable {
    pub fn new() -> Self {
        Self {
            symbols: HashMap::new(),
            text_to_id: HashMap::new(),
            id_to_symbol: HashMap::new(),
            next_id: 0,
            current_time: 0,
        }
    }
    
    // 添加符号到符号表
    pub fn add_symbol(&mut self, text: String, symbol_type: SymbolType) -> usize {
        // 检查符号是否已存在
        if let Some(&id) = self.text_to_id.get(&text) {
            // 更新频率和最后访问时间
            if let Some(symbol) = self.symbols.get_mut(&id) {
                symbol.frequency += 1.0;
                symbol.last_access = self.current_time;
            }
            return id;
        }
        
        // 创建新符号
        let id = self.next_id;
        self.next_id += 1;
        
        let symbol = Symbol {
            text: text.clone(),
            symbol_type,
            frequency: 1.0,
            last_access: self.current_time,
            relations: HashMap::new(),
        };
        
        self.symbols.insert(id, symbol);
        self.text_to_id.insert(text, id);
        self.id_to_symbol.insert(id, self.symbols[&id].text.clone());
        
        id
    }
    
    // 获取符号ID，如果不存在则创建
    pub fn intern(&mut self, text: &str) -> usize {
        let text = text.to_string();
        
        // 确定符号类型
        let symbol_type = if text.chars().all(|c| c.is_ascii_punctuation()) {
            SymbolType::Punctuation
        } else if text.chars().all(|c| c.is_ascii_digit()) {
            SymbolType::Number
        } else if text.chars().all(|c| c.is_alphabetic()) {
            SymbolType::Word
        } else {
            SymbolType::Unknown
        };
        
        self.add_symbol(text, symbol_type)
    }
    
    // 获取符号文本
    pub fn get_text(&self, id: usize) -> Option<&String> {
        self.id_to_symbol.get(&id)
    }
    
    // 获取符号
    pub fn get_symbol(&self, id: usize) -> Option<&Symbol> {
        self.symbols.get(&id)
    }
    
    // 获取符号（可变引用）
    pub fn get_symbol_mut(&mut self, id: usize) -> Option<&mut Symbol> {
        self.symbols.get_mut(&id)
    }
    
    // 分词并转换为符号ID序列
    pub fn tokenize(&mut self, text: &str) -> Vec<String> {
        tokenize(text)
    }
    
    // 将文本转换为符号ID序列
    pub fn text_to_symbols(&mut self, text: &str) -> Vec<usize> {
        let tokens = self.tokenize(text);
        tokens.into_iter().map(|t| self.intern(&t)).collect()
    }
    
    // 将符号ID序列转换为文本
    pub fn symbols_to_text(&self, symbols: &[usize]) -> String {
        let mut result = String::new();
        let mut prev_was_chinese = false;
        
        for &sym_id in symbols {
            if let Some(text) = self.get_text(sym_id) {
                let is_chinese = is_chinese_text(text);
                
                // 在中英文混合时添加适当的空格
                if !result.is_empty() && prev_was_chinese && !is_chinese && !text.chars().all(|c| c.is_ascii_punctuation()) {
                    result.push(' ');
                } else if !result.is_empty() && !prev_was_chinese && is_chinese && !result.ends_with(' ') {
                    result.push(' ');
                }
                
                result.push_str(text);
                prev_was_chinese = is_chinese;
            }
        }
        
        result
    }
    
    // 更新符号关系
    pub fn update_symbol_relation(&mut self, id1: usize, id2: usize, strength: f32) {
        if let Some(symbol) = self.symbols.get_mut(&id1) {
            *symbol.relations.entry(id2).or_insert(0.0) += strength;
        }
    }
    
    // 获取符号关系强度
    pub fn get_relation_strength(&self, id1: usize, id2: usize) -> f32 {
        if let Some(symbol) = self.symbols.get(&id1) {
            symbol.relations.get(&id2).copied().unwrap_or(0.0)
        } else {
            0.0
        }
    }
    
    // 更新时间
    pub fn update_time(&mut self) {
        self.current_time += 1;
    }
    
    // 获取符号数量
    pub fn len(&self) -> usize {
        self.symbols.len()
    }
    
    // 应用时间衰减
    pub fn apply_time_decay(&mut self, decay_factor: f32) {
        for symbol in self.symbols.values_mut() {
            symbol.frequency *= decay_factor;
            
            // 对关系也应用时间衰减
            for strength in symbol.relations.values_mut() {
                *strength *= decay_factor;
            }
        }
    }
}